﻿#region Using

using System.Threading.Tasks;
using Vk.Methods.Common;
using Vk.Methods.Users;

#endregion

namespace Vk.Methods.Auth
{
    public class Auth
    {
        private readonly Api _api;

        public Auth(Api api)
        {
            _api = api;
        }

        /// <summary>
        ///     Проверяет правильность введённого номера.
        /// </summary>
        /// <param name="phone">Номер телефона пользователя.</param>
        /// <param name="clientId">Идентификатор Вашего приложения.</param>
        /// <param name="clientSecret">Секретный ключ Вашего приложения.</param>
        /// <returns>В случае если номер пользователя является правильным будет возвращён true. </returns>
        public async Task<bool> CheckPhone(string phone,
                                           int? clientSecret,
                                           int? clientId = null,
                                           bool? authByPhone = null)
        {
            var query = new ApiQuery("auth.checkPhone")
                .Add("phone", phone)
                .Add("client_id", clientId)
                .Add("client_secret", clientSecret)
                .Add("auth_by_phone", authByPhone);

            var result = await _api.Manager.Execute(query);
            var boolean = result.Bool();
            return _api.Manager.MethodSuccessed && boolean.HasValue && boolean.Value;
        }

        /// <summary>
        ///     Завершает регистрацию нового пользователя, начатую методом auth.signup, по коду, полученному через SMS.
        /// </summary>
        /// <param name="phone">
        ///     Номер телефона регистрируемого пользователя. Номер телефона может быть проверен заранее методом
        ///     auth.checkPhone.
        /// </param>
        /// <param name="code">Код, полученный через SMS в результате выполнения метода auth.signup.</param>
        /// <param name="clientId">Идентификатор Вашего приложения.</param>
        /// <param name="clientSecret">Секретный ключ Вашего приложения.</param>
        /// <param name="password">
        ///     Пароль пользователя, который будет использоваться при входе. Не меньше 6 символов. Также пароль
        ///     может быть указан ранее, при вызове метода auth.signup.
        /// </param>
        /// <param name="testMode">
        ///     true — тестовый режим, при котором не будет зарегистрирован новый пользователь, но при этом
        ///     номер не будет проверяться на использованность. false — (по умолчанию) рабочий.
        /// </param>
        /// <param name="intro">Битовая маска отвечающая за прохождение обучения использованию приложения. </param>
        public async Task<RegisterSuccess> Confirm(string phone,
                                                   string code,
                                                   int clientId,
                                                   int clientSecret,
                                                   string password = null,
                                                   bool? testMode = null,
                                                   int? intro = null)
        {
            var query = new ApiQuery("auth.confirm")
                .Add("phone", phone)
                .Add("client_id", clientId)
                .Add("client_secret", clientSecret)
                .Add("code", code)
                .Add("password", password)
                .Add("test_mode", testMode)
                .Add("intro", intro);

            var result = await _api.Manager.Execute(query);
            return _api.Manager.MethodSuccessed ? new RegisterSuccess(result) : null;
        }

        /// <summary>
        ///     Регистрирует нового пользователя по номеру телефона.
        /// </summary>
        /// <param name="phone">
        ///     Номер телефона регистрируемого пользователя. Номер телефона может быть проверен заранее методом
        ///     auth.checkPhone.
        /// </param>
        /// <param name="firstName">Имя пользователя.</param>
        /// <param name="lastName">Фамилия пользователя.</param>
        /// <param name="clientId">Идентификатор Вашего приложения.</param>
        /// <param name="clientSecret">Секретный ключ Вашего приложения.</param>
        /// <param name="sex">Пол пользователя: 1 - Женский, 2 - Мужской.</param>
        /// <param name="password">
        ///     Пароль пользователя, который будет использоваться при входе. Не меньше 6 символов. Также пароль
        ///     может быть указан позже, при вызове метода auth.confirm.
        /// </param>
        /// <param name="voice">
        ///     true - в случае если вместо SMS необходимо позвонить на указанный номер и продиктовать код голосом.
        ///     false - (по умолчанию) необходимо отправить SMS.
        /// </param>
        /// <param name="sid">
        ///     Идентификатор сессии, необходимый при повторном вызове метода, в случае если SMS сообщение доставлено
        ///     не было.
        /// </param>
        /// <param name="testMode">
        ///     true - тестовый режим, при котором не будет зарегистрирован новый пользователь, но при этом
        ///     номер не будет проверяться на использованность. false - (по умолчанию) рабочий.
        /// </param>
        /// <returns>
        ///     В случае успешного выполнения метода на номер телефона, указанный пользователем, будет отправлено SMS со
        ///     специальным кодом, который может быть использован для завершения регистрации методом auth.confirm.
        ///     В качестве ответа будет возвращено поле sid, необходимое для повторного вызова метода, в случае если SMS-сообщение
        ///     не дошло.
        /// </returns>
        public async Task<int> Signup(string phone,
                                      string firstName,
                                      string lastName,
                                      int clientId,
                                      int clientSecret,
                                      ApiEnum<UserSex> sex = null,
                                      string password = null,
                                      bool? voice = null,
                                      int? sid = null,
                                      bool? testMode = null)
        {
            var query = new ApiQuery("auth.signup")
                .Add("phone", phone)
                .Add("first_name", firstName)
                .Add("last_name", lastName)
                .Add("client_id", clientId)
                .Add("client_secret", clientSecret)
                .Add("sex", sex)
                .Add("password", password)
                .Add("voice", voice)
                .Add("sid", sid)
                .Add("test_mode", testMode);


            var result = await _api.Manager.Execute(query);
            var sidResult = result.Int("sid");
            return _api.Manager.MethodSuccessed && sidResult.HasValue ? sidResult.Value : -1;
        }
    }
}